#include "../classifier_test/all.h"

using namespace classifier_test;

command_line_options_handler Handler;
string NamesFilename;
string StreamFilename;
string SchemeFilename;
bool InfBound;

void init_handler(int argc, char* argv[])
{
	Handler
		.add_usage("<names_file> <stream_file> <scheme_file>")
		.add_usage("--help");
	Handler.options()
		.add("help").set_info("Display this information")
		.add("inf").set_argument("{0,1}", "1").set_info("Whether set bounds of continuous attributes to infinity");
	Handler.set_arguments(argc, argv);
	Handler.set_front_info("Convert a names file to scheme file making use of a specified stream file");
	Handler.set_back_info(
		"Example: " + Handler.get_program_name() + " stagger.names stagger.data stagger.scheme\n"
		"This program is written by Shixi Chen <xreborner@163.com>");
}

void process_arguments(const command_line_arguments& Args)
{
	if (Args.empty())
	{
		Handler.show_usages();
		exit(0);
	}
	if (!Args["help"].empty())
	{
		Handler.show_help();
		exit(0);
	}
	InfBound = to_int(Args["inf"].get_or_default("0")) != 0;
	if (Args[""].size() != 3)
		throw command_line_option_error("Incorrect number of arguments");
	NamesFilename = Args[""][0];
	StreamFilename = Args[""][1];
	SchemeFilename = Args[""][2];
}

int mymain(int argc, char* argv[])
{
	init_handler(argc, argv);
	try
	{
		process_arguments(command_line_arguments(Handler.options(), Handler.parse()));
	}
	catch (command_line_option_error& E)
	{
		checked_printf("%s: %s\n", Handler.get_program_name().c_str(), E.what());
		exit(1);
	}

	record_scheme Scheme;
	Scheme.load_names(NamesFilename);
	smart_ptr<data_file_stream> Stream(new data_file_stream);
	Stream->set_scheme(Scheme);
	Stream->set_have_time(false);
	Stream->set_learn_scheme(true);
	Stream->open(StreamFilename, "r");

	stream_record Rec;
	int Count = 0;
	logger::task LTask = clogger()->info("Reading stream file");
	while (!Stream->eof())
	{
		if (Count % 1000 == 0) LTask.progress(to_string(Count) + " records have been read");
		Stream->read(Rec);
		Count++;
	}
	LTask.end();
	clogger()->info("There totally " + to_string(Count) + " records");
	Scheme = Stream->get_scheme();
	for (int I = 0; I < Scheme.size(); I++) Scheme[I].discr.sort();
	if (InfBound)
		for (int I = 0; I < Scheme.size(); I++)
			if (Scheme[I].type == cont_attr)
				Scheme[I].cont.lower_bound = -numeric_limits<float>::max(),
				Scheme[I].cont.upper_bound = numeric_limits<float>::max();
	Scheme.save(SchemeFilename);

	return 0;
}

int main(int argc, char* argv[])
{
	return safe_main(mymain, argc, argv);
}
